<?php

namespace App\Modules\Popularize\Platform;


use App\Http\Model\Device;
use App\Http\Model\MonitoringLink\AccessToken;
use App\Http\Model\UserRegisterLog;
use Illuminate\Support\Facades\Redis;

/**
 * 检测链接文档
 * https://developer.huawei.com/consumer/cn/doc/distribution/promotion/bp-functions-link-configure-0000001351658397
 * 回传文档
 * https://developer.huawei.com/consumer/cn/doc/distribution/promotion/bp-functions-ocpd-interface-return-0000001238484400
 */

class PlatformHuawei implements PlatformInterface
{

    protected $callback;
    protected $platform;
    protected $device;
    protected $userId;

    const ACTIVITE_EVENT = 1;
    const TWO_ACTIVITE_EVENT = 3;
    const REGISTER_EVENT = 7;
    const PAY_EVENT = 4;

    private $event = [
        self::ACTIVITE_EVENT => '激活',
        self::TWO_ACTIVITE_EVENT => '次日留存',
        self::REGISTER_EVENT => '注册',
        self::PAY_EVENT => '付费'
    ];

    protected $redisPay = 'ADVERTISEMENT:HUAWEI:PAY:%s'; //汇报记录，防止多次汇报


    public function __construct($callback, $platform, $device, $userId = 0)
    {
        $this->callback = $callback;
        $this->platform = $platform;
        $this->device = $device;
        $this->userId = $userId;
    }

    public function active(): ?bool
    {
        if (empty($this->device->guid)) {
            write_log('Platform', 'platform_huawei', ["激活时guid为空", $this->device]);
            return false;
        }

        //处理激活
        $this->_active();
        //处理次日留存
        $this->_twoActvite();
        return true;
    }

    //处理激活
    private function _active(): ?bool{

        //查询是否存在设备信息，如果存在就说明设备已经激活
        $deviceModel = new Device();
        $deviceInfo = $deviceModel->getByGuid($this->device->guid);
        $device = $deviceInfo[0] ?? [];
        if (!empty($device)) {
            return true;
        }

        $params = json_decode(json_encode($this->device), true);

        try {
            $deviceModel = new Device();

            //老的逻辑中，有一些88开头的，全部替换成huawei
            $params['platform'] = $this->platform;
            if (strpos($this->platform,"huawei")  === false){
                $params['platform'] = "huawei";
            }
            $deviceModel->save($params);

            $this->sendCallBack($this->callback, self::ACTIVITE_EVENT);

            write_log('Platform', 'platform_huawei', ["保存设备信息成功", $params]);

            return true;
        } catch (\Exception $e) {
            write_log('Platform', 'platform_huawei', ["保存设备信息失败", $params, $e->getMessage()]);
            return false;
        }
    }

    //处理次日留存
    private function _twoActvite(): ?bool{
        $model = new UserRegisterLog();
        $userRegisterLog = $model->findRecordByGuid($this->device->guid, ['time']);
        if(empty($userRegisterLog['time'])){
            return true;
        }
        $nextDay = strtotime('+1 day', $userRegisterLog['time']);
        $regNextDate = date('Ymd', $nextDay);
        $cuDate = date("Ymd");
        if ($cuDate == $regNextDate){
            $this->sendCallBack($this->callback, self::TWO_ACTIVITE_EVENT);
        }

        return true;
    }

    public function regist(): ?bool
    {
        $callbackUrl = $this->getCallback();
        $this->sendCallBack($callbackUrl, self::REGISTER_EVENT);
        return true;
    }

    public function pay($amount = 0): ?bool
    {
        //只上报一次
        $key = sprintf($this->redisPay, $this->userId);
        $ret = Redis::set($key, 1, 'nx', 'ex', 86400 * 10);
        if (!$ret) {
            return false;
        }

        //获取设备注册时间
        $device = $this->getDevice();
        $created_at = $device->created_at ?? 0;
        if (!$created_at) {
            return false;
        }
        $created_day = date('Ymd', $created_at);

        $payTime = strtotime('+8 day', strtotime($created_day));
        if (time() > $payTime) {
            return false;
        }

        $callbackUrl = $this->getCallback();
        $this->sendCallBack($callbackUrl, self::PAY_EVENT, $amount);

        return true;
    }

    /**
     * 获取华为推广归因参数
     * @return mixed|void
     */
    public function getCallback()
    {
        $data = (new Device())->getByGuid($this->device->guid);
        return empty($data[0]['callback']) ? false : $data[0]['callback'];
    }


    /**
     * 获取设备信息
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|void|null
     */
    public function getDevice()
    {
        return $this->device;
    }


    /**
     * 华为推送请求
     * @param string $callBack
     * @param int $actionType 推送类型
     * @param int $amount 付费金额
     */
    public function sendCallBack($callBack, $actionType, $amount = 0)
    {
        if (empty($callBack)) {
            return false;
        }

        $deviceInfo = $this->getDevice();
        if (!$deviceInfo || !$deviceInfo->oaid) {
            return false;
        }

        $oAid = $deviceInfo->oaid;
        $accessToken = (new AccessToken())->getHuaWeiAccessToken();
        if (!$accessToken) {
            return false;
        }
        $requestUrl = 'https://connect-api.cloud.huawei.com/api/datasource/v1/track/activate';
        $requestHeader = [
            'Authorization:Bearer ' . $accessToken,
            'client_id:' . AccessToken::CLIENT_ID_HUAWEI,
        ];

        $time = time() * 1000;
        $requestParams = [
            'appId' => '101651805',
            'deviceIdType' => 'OAID',
            'deviceId' => $oAid,
            'actionTime' => $time - (8 * 3600 * 1000),//UTC时间
            'actionType' => $actionType,
            'callBack' => $callBack,
        ];

        if ($amount > 0) {
            $action = [
                [
                    'name' => '付费金额',
                    'value' => $amount,
                ]
            ];
            $requestParams['actionParam'] = json_encode($action);
        }

        $requestParamsLog = $requestParams;
        $requestParamsLog['actionTypeDesc'] = $this->event[$actionType];
        $requestParamsLog['guid'] = $this->device->guid;
        $curlMd5 = md5(json_encode($requestParamsLog));
        write_log('HuaweiPopularize', 'platform_huawei curl params ' . $curlMd5, $requestParamsLog);

        try {
            $result = curl_request($requestUrl, $requestParams, 'json', 'POST', $requestHeader);
        } catch (\Throwable $exception) {
            $result = substr($exception->getMessage(), 0, 1000);//保证更新字段时没有错误
        }
        write_log('HuaweiPopularize', 'platform_huawei curl result ' . $curlMd5, $result);
        return true;
    }
}
